package com.org.redis.redisson;

import com.org.redis.config.RedissonConfig;
import org.redisson.Redisson;
import org.redisson.api.*;
import org.redisson.api.listener.MessageListener;

import java.util.concurrent.ExecutionException;
import java.util.function.BiConsumer;

/**
 * 分布式映射集map，与hashmap不同，因为rmap保持的元素的插入顺序
 * @author wang
 */
public class RMapDemo {


    //测试RMap的插入和取值
    public static void rmapSetGet(Redisson redisson){
        RMap<String,User> rMap = redisson.getMap("rmap_test");
        rMap.put("1",new User("ty1"));
        rMap.put("2",new User("ty2"));
        rMap.put("3",new User("ty3"));

        User user = rMap.get("2");
        System.out.println(user.getName());  //------ty2
    }

    //测试rmap的异步方法
    public static void rmapAsync() throws ExecutionException, InterruptedException {
        Redisson redisson = RedissonConfig.getReddsion();
        RMap<String,User> rMap = redisson.getMap("rmap_test");
        RFuture<Integer> rFuture = rMap.sizeAsync();
        System.out.println(rFuture.get());
    }

    /**
     * 可以生成一个LRU的map作缓存
     * @throws Exception
     */
    public static void rmapLRU(Redisson redisson) throws Exception {
        RMapCache<Integer, Integer> map = redisson.getMapCache("LRUMap");

        map.setMaxSize(3);
        map.put(1,1);
        map.put(2,2);
        map.put(3,3);
        map.put(4,4);

        map.forEach( (k,v) -> {
            System.out.println(k+"->"+v);
        });
    }

    /**
     * 字段锁
     * @param redisson
     * @throws Exception
     */
    public static void fieldLock(Redisson redisson) throws Exception {
        RMap<MyKey, MyKey> map = redisson.getMap("map");
        MyKey key = new MyKey();
        RLock rLock = map.getLock(key);
        rLock.lock();
        try {
            //TODO NOTHING
        }finally {
            rLock.unlock();
        }
    }

    /**
     * 测试地理位置容器
     * @param redisson
     * @throws Exception
     */
    public static void address(Redisson redisson) throws Exception {
        RGeo<String> geo = redisson.getGeo("address");
        geo.add(new GeoEntry(13.361389, 38.115556, "Palermo"),
                new GeoEntry(15.087269, 37.502669, "Catania"));

        geo.addAsync(37.618423, 55.751244, "Moscow");

        Double distance = geo.dist("Palermo", "Catania", GeoUnit.METERS);
        System.out.println(distance);
    }

    /**
     * 操作redis原子类
     * @param redisson
     * @throws Exception
     */
    public static void atomic(Redisson redisson) throws Exception {
        RAtomicLong atomicLong = redisson.getAtomicLong("atomic_long");
        atomicLong.incrementAndGet();
        //异步
        RFuture<Boolean> rFuture = atomicLong.compareAndSetAsync(300, 1);

        //方法1:异步回调结果
//        rFuture.thenAccept(res->{
//            if(res) System.out.println("执行成功");
//            else System.out.println("执行失败");
//        });
        System.out.println(atomicLong.get());

        //方法2:完成时候回调的方法
        rFuture.whenComplete((res,exception) -> {

        });
        //不使用lambda就这样
        rFuture.whenComplete(new BiConsumer<Boolean, Throwable>() {
            @Override
            public void accept(Boolean res, Throwable exception) {
                System.out.println("res:" + res);
                System.out.println("exception:" + exception);
            }
        });
    }


    public static void pubAndSub(Redisson redisson){
        RTopic topic = redisson.getTopic("topic_test");

    }

    public static void main(String[] args) throws Exception {
        Redisson redisson = RedissonConfig.getReddsion();//create

        //rmapSetGet(redisson);
        rmapLRU(redisson);

        Thread.sleep(5000);
        redisson.shutdown();//close
    }

}

